package com.boxman

import android.graphics.BitmapFactory
import android.os.Bundle

import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.systemBarsPadding
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Button
import androidx.compose.material3.IconButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.unit.dp
import androidx.constraintlayout.compose.ConstraintLayout

import com.boxman.Game.Status
import com.boxman.ui.theme.BoxmanTheme
import com.common.InputBox
import com.common.MessageBox

// 主活动
class MainActivity: ComponentActivity() {
    private lateinit var mGame: Game                // 游戏
    private lateinit var mInputBox: InputBox        // 输入窗口
    private lateinit var mMessageBox: MessageBox    // 消息窗口

    /**
     * 界面布局。
     */
    @Composable
    fun Greeting() {
        // 计算格的尺寸
        BaseGameObject.sSize = resources.displayMetrics.widthPixels / Const.GAME_BOARD_GRID_COUNT_H

        // 计算游戏区域的尺寸
        val gameBoardSize = BaseGameObject.sSize * Const.GAME_BOARD_GRID_COUNT_H

        // 布局
        ConstraintLayout(Modifier
            .fillMaxSize()
            .systemBarsPadding()
            .background(Const.ACTIVITY_COLOR)
        ) {
            // 初始化成员
            mInputBox.Greeting(0)
            mMessageBox.Greeting()

            val (gameBoard, undo, selectLevel, restart, information, left, up, right, down) = createRefs()

            // 游戏区域
            mGame.GameBoard(
                Modifier.constrainAs(gameBoard) {
                    start.linkTo(parent.start)
                    top.linkTo(parent.top)
                },
                gameBoardSize.toFloat()
            )

            val buttonWidth = remember {
                mutableFloatStateOf(0f)
            }

            // "重新开始"按钮
            Button(
                onClick = onButtonRestartClicked,
                modifier = Modifier
                    .padding(start = Const.ACTIVITY_HORIZONTAL_MARGIN.dp)
                    .constrainAs(restart) {
                        start.linkTo(parent.start)
                        bottom.linkTo(selectLevel.top)
                    }
                    .onSizeChanged {
                        buttonWidth.floatValue = it.width / resources.displayMetrics.density
                    }
            ) {
                Text(this@MainActivity.getString(R.string.IDS_RESTART))
            }

            // "选关"按钮
            Button(
                onClick = onButtonSelectLevelClicked,
                modifier = Modifier
                    .padding(start = Const.ACTIVITY_HORIZONTAL_MARGIN.dp)
                    .width(buttonWidth.floatValue.dp)
                    .constrainAs(selectLevel) {
                        start.linkTo(parent.start)
                        bottom.linkTo(undo.top)
                    }
            ) {
                Text(this@MainActivity.getString(R.string.IDS_SELECT_LEVEL))
            }

            // "回退"按钮
            Button(
                onClick = onButtonUndoClicked,
                modifier = Modifier
                    .padding(
                        start = Const.ACTIVITY_HORIZONTAL_MARGIN.dp,
                        bottom = Const.ACTIVITY_VERTICAL_MARGIN.dp
                    )
                    .width(buttonWidth.floatValue.dp)
                    .constrainAs(undo) {
                        start.linkTo(parent.start)
                        bottom.linkTo(parent.bottom)
                    }
            ) {
                Text(this@MainActivity.getString(R.string.IDS_UNDO))
            }

            // 信息标签
            Text(
                text = super.getString(R.string.IDS_INFORMATION, mGame.level, mGame.moveCount),
                modifier = Modifier
                    .padding(
                        end = Const.ACTIVITY_HORIZONTAL_MARGIN.dp,
                        bottom = Const.ACTIVITY_VERTICAL_MARGIN.dp
                    )
                    .constrainAs(information) {
                        end.linkTo(parent.end)
                        bottom.linkTo(parent.bottom)
                    }
            )

            // 向右按钮
            IconButton(
                onClick = {
                    mGame.onFling(Const.DIRECTION_RIGHT)
                },
                modifier = Modifier
                    .padding(
                        end = Const.ACTIVITY_HORIZONTAL_MARGIN.dp,
                        bottom = Const.ACTIVITY_CONTROL_MARGIN.dp
                    )
                    .constrainAs(right) {
                        end.linkTo(parent.end)
                        bottom.linkTo(information.top)
                    }
            ) {
                Image(BitmapFactory.decodeResource(resources, R.mipmap.button_right).asImageBitmap(), "")
            }

            // 向下按钮
            IconButton(
                onClick = {
                    mGame.onFling(Const.DIRECTION_DOWN)
                },
                modifier = Modifier
                    .padding(bottom = Const.ACTIVITY_CONTROL_MARGIN.dp)
                    .constrainAs(down) {
                        end.linkTo(right.start)
                        bottom.linkTo(information.top)
                    }
            ) {
                Image(BitmapFactory.decodeResource(resources, R.mipmap.button_down).asImageBitmap(), "")
            }

            // 向左按钮
            IconButton(
                onClick = {
                    mGame.onFling(Const.DIRECTION_LEFT)
                },
                modifier = Modifier
                    .padding(bottom = Const.ACTIVITY_CONTROL_MARGIN.dp)
                    .constrainAs(left) {
                        end.linkTo(down.start)
                        bottom.linkTo(information.top)
                    }
            ) {
                Image(BitmapFactory.decodeResource(resources, R.mipmap.button_left).asImageBitmap(), "")
            }

            // 向上按钮
            IconButton(
                onClick = {
                    mGame.onFling(Const.DIRECTION_UP)
                },
                modifier = Modifier.constrainAs(up) {
                    end.linkTo(right.start)
                    bottom.linkTo(down.top)
                }
            ) {
                Image(BitmapFactory.decodeResource(resources, R.mipmap.button_up).asImageBitmap(), "")
            }

            // 信息窗口
            if (mGame.status == Status.WON) {
                mMessageBox.show(
                    tipText = super.getString(R.string.IDS_WON),
                    okButtonText = super.getString(android.R.string.ok),
                    onOK = {
                        mGame.gotoNextLevel()
                    }
                )
            } else if (mGame.status == Status.WON_ALL) {
                mMessageBox.show(
                    tipText = super.getString(R.string.IDS_WON_ALL_OVER),
                    okButtonText = super.getString(android.R.string.ok)
                )
            }
        }
    }

    /**
     * "重玩本关"按钮的单击响应方法。
     */
    private val onButtonRestartClicked = fun() {
        mGame.restart()
    }

    /**
     * "选关"按钮的单击响应方法。
     */
    private val onButtonSelectLevelClicked = fun() {
        // 显示输入窗口
        val tipText = super.getString(R.string.IDS_PLEASE_INPUT_NUMBER, Const.LEVEL_COUNT)
        mInputBox.show(mGame.level, Const.LEVEL_COUNT, 1, {}, { mGame.gotoLevel(it) }, tipText)
    }

    /**
     * "回退"按钮的单击响应方法。
     */
    private val onButtonUndoClicked = fun() {
        mGame.undo()
    }

    /**
     * 创建事件的响应方法。
     * @param savedInstanceState    保存的实例状态
     */
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        this.enableEdgeToEdge()

        // 初始化成员
        mGame = Game(resources.assets)
        mInputBox = InputBox()
        mMessageBox = MessageBox()

        // 设置内容
        this.setContent {
            BoxmanTheme {
                this.Greeting()
            }
        }
    }
}
